package org.jsola.hr.service.impl;

import lombok.extern.slf4j.Slf4j;
import org.jsola.hr.common.HrLogKit;
import org.jsola.hr.constant.EmpInfoScene;
import org.jsola.hr.constant.HrConstants;
import org.jsola.hr.dto.*;
import org.jsola.hr.entity.CompanyDO;
import org.jsola.hr.provider.IPermissionProviderService;
import org.jsola.hr.provider.IUserProviderService;
import org.jsola.hr.service.*;
import org.jsola.hr.vo.DepInfoVO;
import org.jsola.hr.vo.PositionInfoVO;
import org.jsola.module.ModuleContext;
import org.jsola.user.core.TokenUser;
import org.jsola.user.entity.UserDO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Objects;

import static org.jsola.hr.constant.HrPermissionConstants.HR_DEFAULT_SUBJECT_ID;

/**
 * @author june
 */
@Service
@Slf4j
public class HrCompanyModuleServiceImpl implements ICompanyModuleService {

    @Autowired
    private IDepInfoService depInfoService;

    @Autowired
    private IPositionInfoService positionInfoService;

    @Autowired
    private ICompanyEmpInfoRequireService empInfoRequireService;

    @Autowired
    private IEmpContactsRequireService contactsRequireService;

    @Autowired
    private IEmpWorkRequireService workRequireService;

    @Autowired
    private IEmpEducationRequireService educationRequireService;

    @Autowired
    private IEmpCardRequireService cardRequireService;

    @Autowired
    private IEmpTrainRequireService trainRequireService;

    @Autowired
    private IEmpCertificateRequireService certificateRequireService;

    @Autowired
    private IPermissionProviderService permissionProviderService;

    @Autowired
    private IUserProviderService userProviderService;

    @Autowired
    private ICompanyEmpNecessaryService companyEmpNecessaryService;

    @Autowired
    private IEmpInfoService empInfoService;

    @Autowired
    private ICompanyNecessaryFieldService companyNecessaryFieldService;

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public ModuleContext initCompany(ModuleContext moduleContext) {
        // 值
        TokenUser tokenUser = new TokenUser(moduleContext.getCurrUserId(), moduleContext.getSiteId());
        UserDO userDO = userProviderService.selectUserById(moduleContext.getCurrUserId());
        if(null != userDO){
            tokenUser.setUserName(userDO.getName());
        }
        // 根据公司初始化部门
        initDeptByCompany(moduleContext, tokenUser);
//
//        // 初始化当前用户为公司管理员
//        initCompanyAdminRoleMember(tokenUser, moduleContext);

        // 根据公司初始化岗位
        initPositionByCompany(moduleContext, tokenUser);
//
//        // 初始化话公司员工信息
//        initEmpInfoRequireByCompany(moduleContext, tokenUser);

        // 初始化一些审批
        CompanyDO company = moduleContext.get("companyDO");
//        approInitializerProviderService.initApproval(company.getId(), tokenUser);
//        HrLogKit.logForSave("新增公司时初始化公司审批,name:" + company.getName(), "initApprovalByCompany", company.getId(), tokenUser);

        //初始化小程序个人信息必填项
        companyEmpNecessaryService.insertCompany(company.getId(), tokenUser);
        // 初始化公司的必填项
        companyNecessaryFieldService.necessaryInitializationByCompanyId(company.getId(), tokenUser);

        return moduleContext;
    }

    /**
     * 根据公司初始化部门
     *
     * @param moduleContext 上下文
     * @param tokenUser     当前用户
     */
    private void initDeptByCompany(ModuleContext moduleContext, TokenUser tokenUser) {

        CompanyDO company = moduleContext.get("companyDO");
        // 获取一级,一级是用siteId做的code
        DepInfoVO depInfoSite = depInfoService.selectByCode(tokenUser.getSiteId(), tokenUser.getSiteId(), null);
        if (Objects.isNull(depInfoSite)) {
            // 没有站点级部门,增加一下
            depInfoSite = initDeptInfo(tokenUser);
        }

        // 增加公司二级
        DepInfoAddDTO depInfoAddDTO = new DepInfoAddDTO();
        depInfoAddDTO.setName(company.getName());
        depInfoAddDTO.setParentId(depInfoSite.getId());
        depInfoAddDTO.setLevel(2);
        depInfoAddDTO.setCode(company.getId());
        depInfoAddDTO.setVirural(false);
        depInfoAddDTO.setCompanyId(company.getId());
        depInfoAddDTO.setType(0);
        depInfoAddDTO.setSort(100);
        DepInfoVO depInfoCompany = depInfoService.save(depInfoAddDTO, tokenUser);

        // 返回部门id,修改公司表
        moduleContext.add("depId", depInfoCompany.getId());
        log.info("人力层级增加公司成功,siteId:{},company:{}", tokenUser.getSiteId(), company);
        HrLogKit.logForSave("新增公司时初始化部门,公司名:" + company.getName(), "initDeptByCompany", company.getId(), company.getId(), tokenUser);

    }

    private DepInfoVO initDeptInfo(TokenUser tokenUser) {
        DepInfoAddDTO depInfoAddDTO = new DepInfoAddDTO();
        depInfoAddDTO.setName(tokenUser.getSiteId());
        depInfoAddDTO.setParentId("0");
        depInfoAddDTO.setLevel(1);
        depInfoAddDTO.setCode(tokenUser.getSiteId());
        depInfoAddDTO.setVirural(false);
        depInfoAddDTO.setCompanyId("0");
        depInfoAddDTO.setType(0);
        depInfoAddDTO.setSort(100);
        DepInfoVO depInfoVO = depInfoService.save(depInfoAddDTO, tokenUser);
        log.info("初始化人力系统新建部门成功，siteId:{}", tokenUser.getSiteId());
        return depInfoVO;
    }

    /**
     * 初始化公司管理员
     *
     * @param tokenUser     超管
     * @param moduleContext 上下文
     */
    private void initCompanyAdminRoleMember(TokenUser tokenUser, ModuleContext moduleContext) {

        CompanyDO company = moduleContext.get("companyDO");

        permissionProviderService.addUserToCompanyAdmin(HR_DEFAULT_SUBJECT_ID, tokenUser, tokenUser.getUserId());

        log.info("公司增加管理员成功,siteId:{},userId:{},companyId:{}", tokenUser.getSiteId(), tokenUser.getUserId(), company.getId());
        HrLogKit.logForSave("新增公司时初始化当前员工为管理员,公司名:" + company.getName(), "initCompanyAdminRoleMember", company.getId(), tokenUser);

    }

    /**
     * 根据公司初始化岗位
     *
     * @param moduleContext 上下文
     * @param tokenUser     当前用户
     */
    private void initPositionByCompany(ModuleContext moduleContext, TokenUser tokenUser) {

        CompanyDO company = moduleContext.get("companyDO");
        // 增加公司下岗位
        PositionInfoAddDTO positionInfoAddDTO = new PositionInfoAddDTO();
        positionInfoAddDTO.setType(2);
        positionInfoAddDTO.setName(company.getName());
        positionInfoAddDTO.setCode(company.getId());
        positionInfoAddDTO.setRemark(company.getName() + "的岗位目录");
        positionInfoAddDTO.setDesc("");
        positionInfoAddDTO.setFormalNum(0);
        positionInfoAddDTO.setCompanyId(company.getId());
        positionInfoAddDTO.setLevel(1);
        positionInfoAddDTO.setSort(1);
        positionInfoAddDTO.setParentId("0");

        PositionInfoVO positionInfoVO = positionInfoService.save(positionInfoAddDTO, tokenUser);
        log.info("公司初始化岗位成功,siteId:{},positionInfo:{}", tokenUser.getSiteId(), positionInfoVO);

    }

    /**
     * 初始化话公司员工信息
     *
     * @param moduleContext 上下文
     * @param tokenUser     当前用户
     */
    private void initEmpInfoRequireByCompany(ModuleContext moduleContext, TokenUser tokenUser) {
        CompanyDO company = moduleContext.get("companyDO");

        for (EmpInfoScene empInfoScene : EmpInfoScene.values()) {
            CompanyEmpInfoRequireAddDTO empInfoRequireAddDTO = new CompanyEmpInfoRequireAddDTO();
            empInfoRequireAddDTO.setCompanyId(company.getId());
            empInfoRequireAddDTO.setType(empInfoScene.getValue());
            empInfoRequireService.save(empInfoRequireAddDTO, tokenUser);
            log.info("公司初始化员工所需信息成功,siteId:{},empInfoRequire:{}", tokenUser.getSiteId(), empInfoRequireAddDTO);

            // 公司员工联系人所需信息
            EmpContactsRequireAddDTO contactsRequireAddDTO = new EmpContactsRequireAddDTO();
            contactsRequireAddDTO.setCompanyId(company.getId());
            contactsRequireAddDTO.setRequireType(empInfoScene.getValue());
            contactsRequireService.save(contactsRequireAddDTO, tokenUser);
            log.info("公司初始化员工联系人所需信息成功,siteId:{},empInfoRequire:{}", tokenUser.getSiteId(), empInfoRequireAddDTO);


            // 公司员工工作经历所需信息
            EmpWorkRequireAddDTO workRequireAddDTO = new EmpWorkRequireAddDTO();
            workRequireAddDTO.setCompanyId(company.getId());
            workRequireAddDTO.setRequireType(empInfoScene.getValue());
            workRequireService.save(workRequireAddDTO, tokenUser);
            log.info("公司初始化员工工作经历所需信息成功,siteId:{},empInfoRequire:{}", tokenUser.getSiteId(), empInfoRequireAddDTO);


            // 公司员工教育经历所需信息
            EmpEducationRequireAddDTO educationRequireAddDTO = new EmpEducationRequireAddDTO();
            educationRequireAddDTO.setCompanyId(company.getId());
            educationRequireAddDTO.setRequireType(empInfoScene.getValue());
            educationRequireService.save(educationRequireAddDTO, tokenUser);
            log.info("公司初始化员工教育经历所需信息成功,siteId:{},empInfoRequire:{}", tokenUser.getSiteId(), empInfoRequireAddDTO);


            // 公司员工证件信息所需信息
            EmpCardRequireAddDTO cardRequireAddDTO = new EmpCardRequireAddDTO();
            cardRequireAddDTO.setCompanyId(company.getId());
            cardRequireAddDTO.setRequireType(empInfoScene.getValue());
            cardRequireService.save(cardRequireAddDTO, tokenUser);
            log.info("公司初始化员工证件信息所需信息成功,siteId:{},empInfoRequire:{}", tokenUser.getSiteId(), empInfoRequireAddDTO);


            // 公司员工培训记录所需信息
            EmpTrainRequireAddDTO trainRequireAddDTO = new EmpTrainRequireAddDTO();
            trainRequireAddDTO.setCompanyId(company.getId());
            trainRequireAddDTO.setRequireType(empInfoScene.getValue());
            trainRequireService.save(trainRequireAddDTO, tokenUser);
            log.info("公司初始化员工培训记录所需信息成功,siteId:{},empInfoRequire:{}", tokenUser.getSiteId(), empInfoRequireAddDTO);


            // 公司员工证书所需信息
            EmpCertificateRequireAddDTO certificateRequireAddDTO = new EmpCertificateRequireAddDTO();
            certificateRequireAddDTO.setCompanyId(company.getId());
            certificateRequireAddDTO.setRequireType(empInfoScene.getValue());
            certificateRequireService.save(certificateRequireAddDTO, tokenUser);
            log.info("公司初始化员工证书所需信息成功,siteId:{},empInfoRequire:{}", tokenUser.getSiteId(), empInfoRequireAddDTO);
        }
    }

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public ModuleContext updateCompany(ModuleContext moduleContext) {
        // 值
        TokenUser tokenUser = new TokenUser(moduleContext.getCurrUserId(), moduleContext.getSiteId());
        CompanyDO company = moduleContext.get("companyDO");

        // 根据code获取当前层级
        DepInfoVO depInfoVO = depInfoService.selectByCode(company.getId(), tokenUser.getSiteId(), company.getId());
        if (Objects.isNull(depInfoVO)) {
            return moduleContext;
        }
        DepInfoUpdateDTO depInfoUpdateDTO = new DepInfoUpdateDTO();
        depInfoUpdateDTO.setId(depInfoVO.getId());
        depInfoUpdateDTO.setName(company.getName());
        depInfoUpdateDTO.setCompanyId(company.getId());
        depInfoUpdateDTO.setParentId(depInfoVO.getParentId());
        depInfoService.update(depInfoUpdateDTO, tokenUser);

        log.info("人力层级修改公司成功,siteId:{},company:{}", tokenUser.getSiteId(), company);
        return moduleContext;
    }

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public ModuleContext destroyCompany(ModuleContext moduleContext) {
        TokenUser tokenUser = new TokenUser(moduleContext.getCurrUserId(), moduleContext.getSiteId());
        String[] companyIds = moduleContext.get("companyIds");
        if (companyIds == null || companyIds.length == 0) {
            return moduleContext;
        }
        // 删除部门层级
        for (String companyId : companyIds) {
            // 删除公司下全部岗位
            positionInfoService.deleteByCompanyId(companyId, tokenUser);

            // 删除公司下部门部门
            depInfoService.deleteByCompanyId(companyId, tokenUser);

            // 删除公司下员工
            empInfoService.deleteByCompanyId(companyId, tokenUser);
        }
        log.info("人力层级删除公司成功,siteId:{},companyIds:{}", tokenUser.getSiteId(), companyIds);
        return moduleContext;
    }
}
